﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using System.Linq.Expressions;
using WorkLogSystem.Entity;
using WorkLogSystem.Entity.Model;

namespace WorkLogSystem.Service
{
    public class BaseService<T> where T : BaseEntity, new()
    {
        protected readonly ISqlSugarClient _db;

        protected readonly IHttpContextAccessor _httpContextAccessor;

        private UserInfo _currentUser;

        public BaseService(ISqlSugarClient db,IHttpContextAccessor httpContextAccessor)
        {
            _db = db;
            _httpContextAccessor = httpContextAccessor;
        }

        protected UserInfo CurrentUser
        {
            get
            {
                if (_currentUser != null)
                {
                    return _currentUser;
                }
                else
                {
                    _currentUser = new UserInfo();
                    _currentUser.ID = _httpContextAccessor.HttpContext.User.FindFirst("ID").Value;
                    _currentUser.cUserName = _httpContextAccessor.HttpContext.User.FindFirst("UserName").Value;
                    _currentUser.cGender = _httpContextAccessor.HttpContext.User.FindFirst("Gender").Value;
                    _currentUser.cPhone = _httpContextAccessor.HttpContext.User.FindFirst("Phone").Value;
                    return _currentUser;
                }
            }
        }

        // 添加
        public bool AddItem(T entity)
        {
            entity.ID = Guid.NewGuid().ToString();
            entity.CreateTime = DateTime.Now;
            entity.CreateUserID = CurrentUser.ID;
            entity.CreateUserName = CurrentUser.cUserName;
            entity.UpdateTime = DateTime.Now;
            entity.UpdateUserID = CurrentUser.ID;
            entity.UpdateUserName = CurrentUser.cUserName;
            entity.IsDel = false;
            return _db.Insertable(entity).ExecuteCommand() > 0;
        }

        public bool AddList(List<T> entities)
        {
            return _db.Insertable(entities).ExecuteCommand() > 0;
        }

        public bool UpdateItem(Dictionary<string, object> columnDictionary)
        {
            columnDictionary["UpdateTime"] = DateTime.Now;
            columnDictionary["UpdateUserID"] = CurrentUser.ID;
            columnDictionary["UpdateUserName"] = CurrentUser.cUserName;
            int a = _db.Updateable<T>(columnDictionary).ExecuteCommand();
            return a > 0;
        }

        public bool UpdateList(List<T> entities)
        {
            return _db.Updateable(entities).ExecuteCommand() > 0;
        }

        public bool DeleteItem(Dictionary<string, object> columnDictionary)
        {
            //entity.IsDel = true;
            //entity.UpdateTime = DateTime.Now;
            //entity.UpdateUserID = CurrentUser.ID;
            //entity.UpdateUserName = CurrentUser.cUserName;
            columnDictionary["IsDel"] = true;
            columnDictionary["UpdateTime"] = DateTime.Now;
            columnDictionary["UpdateUserID"] = CurrentUser.ID;
            columnDictionary["UpdateUserName"] = CurrentUser.cUserName;
            return _db.Updateable<T>(columnDictionary).ExecuteCommand() > 0;
        }

        public bool DeleteList(List<string> ids)
        {
            return _db.Deleteable<T>().In(ids).ExecuteCommand() > 0;
        }
        public bool IsExist(Expression<Func<T, bool>> where)
        {
            return _db.Queryable<T>().Any(where);
        }

        public int Count(Expression<Func<T, bool>> where)
        {
            return _db.Queryable<T>().Count(where);
        }

        public T GetItem(T entity)
        {
            return _db.Queryable<T>().InSingle(entity.ID);
        }

        //public List<T> GetAll()
        //{
        //    return _db.Queryable<T>().ToList();
        //}

        public List<T> GetList(PageRequest request)
        {
            var query = _db.Queryable<T>();
            query.Where("IsDel", "=", false);
            if (request.Param != null)
            {
                foreach (var pair in request.Param)
                {
                    if (pair.Value != null && !string.IsNullOrWhiteSpace(pair.Value))
                    {
                        if (pair.Key == "ID" || pair.Key == "ParentID")
                        {
                            query.Where(pair.Key, "=", pair.Value);
                        }
                        else
                        {
                            query.Where(pair.Key, "LIKE", pair.Value + "%");
                        }
                    }
                }
            }

            if (request.Sort != null)
            {
                foreach (string item in request.Sort)
                {
                    query = query.OrderBy(item);
                }
            }
            return query.ToList();
        }


        public PageResult<T> GetPageList(PageRequest request)
        {
            var query = _db.Queryable<T>();

            query.Where("IsDel", "=", false);
            query.Where("CreateUserID", "=", CurrentUser.ID);
            if (request.Param != null)
            {
                foreach (var pair in request.Param)
                {
                    if (pair.Value != null && !string.IsNullOrWhiteSpace(pair.Value))
                    {
                        if (pair.Key == "ID" || pair.Key == "ParentID")
                        {
                            query.Where(pair.Key, "=", pair.Value);
                        }
                        else
                        {
                            query.Where(pair.Key, "LIKE", pair.Value + "%");
                        }
                    }
                }
            }

            if (request.Sort != null)
            {
                foreach (string item in request.Sort)
                {
                    query = query.OrderBy(item);
                }
            }

            var totalCount = 0;
            var data = query.ToPageList(request.PageIndex, request.PageSize, ref totalCount);
            PageResult<T> res = new PageResult<T>();
            res.Data = data;
            res.TotalCount = totalCount;
            res.TotalPages = (int)Math.Ceiling((decimal)totalCount / request.PageSize);
            res.PageIndex = request.PageIndex;
            res.PageSize = request.PageSize;
            return res;
        }
    }
}
